<?php
/**
 * Created by PhpStorm.
 * User: DELL-PC
 * Date: 2018/8/17
 * Time: 12:33
 */

namespace J\Schema;


use J\Schema\Collection\ICollection;
use J\Schema\Collection\Collection;
use J\Exception;
use J\Manager;
use J\Message;

class CollectionManager extends Manager
{
    /**
     * @var array 配置
     */
    protected $config;

    /**
     * @var bool 内部表
     */
    protected $_isInner;

    /**
     * CollectionManager constructor.
     * @param array $config
     * @param bool $isInner
     */
    public function __construct(array $config, $isInner = false)
    {
        $this->config = $config;
        $this->_isInner = $isInner;
    }


    /**
     * 获取集合
     *
     * @param string $name
     * @return ICollection
     * @throws Exception
     */
    public function getCollection($name)
    {
        $key = strtolower($name);
        return $this->getObject($key);
    }

    /**
     * 遍历所有集合
     *
     * @param \Closure $closure function(ICollection $collection)
     * @throws Exception
     */
    public function iterateCollection(\Closure $closure)
    {
        foreach ($this->config as $name => $c) {
            $closure($this->getCollection($name));
        }
    }

    /**
     * 创建对象
     *
     * @param $name
     * @return Collection
     * @throws Exception
     */
    protected function createObject($name)
    {
        $key = strtolower($name);
        if (!isset($this->config[$key]))
            throw new Exception(Message::COLLECTION_NOT_FIND, ['collection' => $name]);
        return new Collection($name, $this, $this->config[$key]);
    }

    /**
     * 获取连接表
     * @param string $ca
     * @param string $cb
     * @return ICollection
     * @throws Exception
     */
    public function getLinker($ca, $cb)
    {
        $name = $this->getLinkerOf($ca, $cb);
        if ($name) return $this->getCollection($name);

        $name = $this->getLinkerOf($cb, $ca);
        if ($name) return $this->getCollection($name);

        throw new Exception(Message::LINKER_NOT_FIND, [
            'he' => $ca,
            'me' => $cb
        ]);
    }

    /**
     * 寻找连接表
     *
     * @param $ca
     * @param $cb
     * @return false|string
     */
    protected function getLinkerOf($ca, $cb)
    {
        $linker = default_table_linker($ca, $cb);

        try {
            $c = $this->getCollection($linker);
            return ($c->belongs($ca) and $c->belongs($cb)) ? $linker : false;
        } catch (\Throwable $e) {
            return false;
        }

    }

    public function isInner()
    {
        return $this->_isInner;
    }
}